﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;

namespace JMT.Controls.Relations.Maths
{
    /// <summary>
    /// 计算连接点
    /// </summary>
    public static class LinkPosUtil
    {
        public static void CalcLinkPos(Rect fromRect, Rect toRect, out Point fromPos, out Point toPos)
        {
            Point fromCenterPos = new Point(fromRect.X + fromRect.Width / 2, fromRect.Y + fromRect.Height / 2);
            Point toCenterPos = new Point(toRect.X + toRect.Width / 2, toRect.Y + toRect.Height / 2);

            // 直线方程 y=kx+b
            // 
            double k = (fromCenterPos.Y - toCenterPos.Y) / (fromCenterPos.X - toCenterPos.X);
            double b = fromCenterPos.Y - (k * fromCenterPos.X);

            if (fromCenterPos.Y < toCenterPos.Y)
            {
                if (fromCenterPos.X < toCenterPos.X)
                {
                    fromPos = new Point();
                    double fx1 = (fromRect.Bottom - b) / k;
                    double fy1 = k * fx1 + b;

                    double fy2 = k * fromRect.Right + b;
                    double fx2 = (fy2 - b) / k;
                    if ((int)fx1 > (int)fromRect.Right || (int)fy1 > (int)fromRect.Bottom)
                    {
                        fromPos = new Point(fx2, fy2);
                    }
                    else
                    {
                        fromPos = new Point(fx1, fy1);
                    }

                    toPos = new Point();
                    double tx1 = (toRect.Top - b) / k;
                    double ty1 = k * tx1 + b;

                    double ty2 = k * toRect.Left + b;
                    double tx2 = (ty2 - b) / k;
                    if ((int)tx1 < (int)toRect.Left || (int)ty1 < (int)toRect.Top)
                    {
                        toPos = new Point(tx2, ty2);
                    }
                    else
                    {
                        toPos = new Point(tx1, ty1);
                    }
                }
                else if (fromCenterPos.X > toCenterPos.X)
                {
                    fromPos = new Point();
                    double fx1 = (fromRect.Bottom - b) / k;
                    double fy1 = k * fx1 + b;

                    double fy2 = k * fromRect.Left + b;
                    double fx2 = (fy2 - b) / k;
                    if ((int)fx1 < (int)fromRect.Left || (int)fy1 > (int)fromRect.Bottom)
                    {
                        fromPos = new Point(fx2, fy2);
                    }
                    else
                    {
                        fromPos = new Point(fx1, fy1);
                    }

                    toPos = new Point();
                    double tx1 = (toRect.Top - b) / k;
                    double ty1 = k * tx1 + b;

                    double ty2 = k * toRect.Right + b;
                    double tx2 = (ty2 - b) / k;
                    if ((int)tx1 > (int)toRect.Right || (int)ty1 < (int)toRect.Top)
                    {
                        toPos = new Point(tx2, ty2);
                    }
                    else
                    {
                        toPos = new Point(tx1, ty1);
                    }
                }
                else
                {
                    fromPos = new Point(fromCenterPos.X, fromRect.Bottom);
                    toPos = new Point(toCenterPos.X, toRect.Top);
                }
            }
            else if (fromCenterPos.Y > toCenterPos.Y)
            {
                if (fromCenterPos.X < toCenterPos.X)
                {
                    fromPos = new Point();
                    double fx1 = (fromRect.Top - b) / k;
                    double fy1 = k * fx1 + b;

                    double fy2 = k * fromRect.Right + b;
                    double fx2 = (fy2 - b) / k;
                    if ((int)fx1 > (int)fromRect.Right || (int)fy1 < (int)fromRect.Top)
                    {
                        fromPos = new Point(fx2, fy2);
                    }
                    else
                    {
                        fromPos = new Point(fx1, fy1);
                    }

                    toPos = new Point();
                    double tx1 = (toRect.Bottom - b) / k;
                    double ty1 = k * tx1 + b;

                    double ty2 = k * toRect.Left + b;
                    double tx2 = (ty2 - b) / k;
                    if ((int)tx1 < (int)toRect.Left || (int)ty1 > (int)toRect.Bottom)
                    {
                        toPos = new Point(tx2, ty2);
                    }
                    else
                    {
                        toPos = new Point(tx1, ty1);
                    }
                }
                else if (fromCenterPos.X > toCenterPos.X)
                {
                    fromPos = new Point();
                    double fx1 = (fromRect.Top - b) / k;
                    double fy1 = k * fx1 + b;

                    double fy2 = k * fromRect.Left + b;
                    double fx2 = (fy2 - b) / k;
                    if ((int)fx1 < (int)fromRect.Left || (int)fy1 < (int)fromRect.Top)
                    {
                        fromPos = new Point(fx2, fy2);
                    }
                    else
                    {
                        fromPos = new Point(fx1, fy1);
                    }

                    toPos = new Point();
                    double tx1 = (toRect.Bottom - b) / k;
                    double ty1 = k * tx1 + b;

                    double ty2 = k * toRect.Right + b;
                    double tx2 = (ty2 - b) / k;
                    if ((int)tx1 > (int)toRect.Right || (int)ty1 > (int)toRect.Bottom)
                    {
                        toPos = new Point(tx2, ty2);
                    }
                    else
                    {
                        toPos = new Point(tx1, ty1);
                    }
                }
                else
                {
                    fromPos = new Point(fromCenterPos.X, fromRect.Top);
                    toPos = new Point(toCenterPos.X, toRect.Bottom);
                }
            }
            else
            {
                if (fromCenterPos.X < toCenterPos.X)
                {
                    fromPos = new Point(fromRect.Right, fromCenterPos.Y);
                    toPos = new Point(toRect.Left, toCenterPos.Y);
                }
                else if (fromCenterPos.X > toCenterPos.X)
                {
                    fromPos = new Point(fromRect.Left, fromCenterPos.Y);
                    toPos = new Point(toRect.Right, toCenterPos.Y);
                }
                else
                {
                    fromPos = new Point(fromCenterPos.X, fromCenterPos.Y);
                    toPos = new Point(toCenterPos.X, toCenterPos.Y);
                }
            }
        }

    }
}
